AcceleratedC++ C3 使用批量数据
Yann 4/17/2018, AcceleratedC++
# 使用批量数据
- 通常需要在程序中处理多个相似数据段
- 编写程序读取学生的考试和家庭作业成绩并计算出总成绩
# 计算学生成绩
- 学生课程总成绩为加权平均
- 第一次尝试的程序如下
#include<iomanip>
#include<ios>
#include<iostream>
#include<string>
using std::cin;
using std::cout;
using std::endl;
using std::setprecision;
using std::string;
using std::streamsize;
int main()
{
//请求输入并读入学生的姓名
cout << "Please Enter your name:";
string name;
cin >> name;
cout << "Hello," << name << "!" << endl;
//请求输入并读入其中和期末成绩
cout << "Please Enter your midterm and final exam grades:";
double midterm,final;
cin >> midterm >> final;
//请求输入家庭作业成绩
cout << "Enter all your homework grades," "Followed by end-of-file:";
//到目前为止,读到的家庭作业成绩的个数及总和
int count = 0;
double sum = 0;
//将家庭作业成绩读到变量x中
double x;
while (cin>>x) {
++count;
sum += x;
}
streamsize prec = cout.precision();
cout << "Your final grade is" << setprecision(3)
<< 0.2 * midterm + 0.4 *final + 0.4 *sum /count << setprecision(prec) << endl;
return 0;
}
库 | 类型 | 作用 |
---|---|---|
<ios> | 类型streamsize | 输入/输出库用这个类型来表示长度 |
<iomanip> | 控制器setprecision | 允许我们指明输出所包含的有效位数 |
# 用中值代替平均值
#include<algorithm>
#include<iomanip>
#include<ios>
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
//请求输入并读入学生姓名
cout << "Please Enter Your Name:";
string name;
cin >> name;
cout << "Hello," << name << "!" << endl;
//请求输入并读入其中和期末成绩
cout << "Please Enter Your midterm and final exam grades:";
double midterm,final;
cin >> midterm >> final;
//请求输入家庭作业成绩
cout << "Enter all your homework grades," "Followed by end-of-file:";
vector<double> homework;
double x;
//不变式:homework包含所有的家庭作业成绩
while (cin>>x)
homework.push_back(x);
//检查homework是否为空
typedef vector<double>::size_type vec_sz;
vec_sz size = homework.size();
if (size == 0) {
cout << endl << "You must enter your grades." "Please tyr again." << endl;
return 1;
}
//对成绩进行排序
sort(homework.begin(),homework.end());
//计算家庭作业成绩的中值
vec_sz mid = size/2;
double median;
median = size % 2 == 0?(homework[mid]+homework[mid-1])/2:homework[mid];
//计算并输出总成绩
streamsize prec = cout.precision();
cout << "Your final grade is" << setprecision(3)
<< 0.2 * midterm + 0.4 *final + 0.4 *median << setprecision(prec) << endl;
return 0;
}
代码 | 含义 |
---|---|
vector<double> homework | 定义homework为一个向量且该向量保存double类型的值 |
homework.push_back(x); | push_back 成员函数操作为添加一个新元素到向量的末尾 |
typedef vector<double>::size_type vec_sz | vector类型定义了一个名为vector<double>::size_type 的类型和一个名为size 的函数 |
typedef | 所定义的名称是特定类型的一个替代名 而不是这种类型的一个变量 |
return 1 | 大部分系统环境都将所有的非0值看作是失败 |
sort | 该函数定义在头文件<algorithm> 中 仅仅调换了原容器中的元素值的相对顺序,而不是创建一个新的容器用于存储排序后的结果 |
% | 取模运算符 返回余数 |
?: | 条件运算符 if-then-else |
# 将数据集合存储到向量中
- 存储大量数值,每次读取一个数值,而且在读数值的时候并不会预先知道数值的个数
- 读取了所有的数值之后对它们进行排序
- 高效获取中间的一个或两个数值
# 更加深入的观察
# homework为空的情况下为什么要退出程序
# size_type
是无符号整数类型
不能存储负数值,故不用检查homework.size()<0
是否成立,因为不等式总是产生false值
# 普通整数-无符号整数转化
普通整数和无符号整数在表达式中结合在一起时,普通整数就要被转换为无符号整数
# 使用标准库时,性能不会太差
# 小结
代码 | 含义 |
---|---|
typedef type name; | 将name定义为type的替代名 |
v.push_back(e) | 给向量添加一个初始值为e的元素 |
while(cin>>x) | 将一个适当类型的值读到x中并检查流的状态 |
s.precision(n) | 为以后的输出将流s的精度设置为n |
setprecision(n) | 返回一个值,在输出流s上写入时,该值具有调用s.precision(n) 的效果 |